Conversation
- 소소한 코드 수정 (자간 수정, 종성에 따른 "이/가" 조건부 렌더링)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Walkthrough결과 페이지에서 중간지점/추천 쿼리 캐시를 무효화하는 로직과 이에 따른 네비게이션(flow)을 router.replace 기반으로 변경했고, 지도 출발지 정보 카드의 최소 너비 및 전송 모달의 스타일/클래스 정리를 함께 적용했습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant ResultPage as ResultPage(Component)
participant QueryClient as QueryClient(Cache)
participant Router as Router
User->>ResultPage: 클릭 (뒤로/수정 시작)
ResultPage->>QueryClient: invalidateQueries('midpoint', id)
ResultPage->>QueryClient: invalidateQueries('recommendation', id)
ResultPage->>Router: router.replace("/meeting/{id}")
Router-->>User: 네비게이션 완료
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/result/[id]/page.tsx (1)
227-227:⚠️ Potential issue | 🟠 Major
tracking-[-1.94%]는 유효하지 않은 CSSletter-spacing값일 수 있습니다.
transferModal.tsx와 동일한 문제입니다. CSSletter-spacing속성은 퍼센트 값을 지원하지 않으므로 브라우저에서 무시될 수 있습니다. px 또는 em 단위 사용을 권장합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/result/`[id]/page.tsx at line 227, Replace the invalid percentage-based letter-spacing class tracking-[-1.94%] in the div with a valid unit-based tracking value (e.g., tracking-[-1.94px] or tracking-[-0.02em]) so browsers won't ignore it; update the className on the div in page.tsx (and mirror the same change in transferModal.tsx where the same tracking-[-1.94%] is used) to use Tailwind arbitrary unit syntax for letter-spacing with px or em units.
🧹 Nitpick comments (3)
app/result/[id]/page.tsx (3)
147-206:getLineColor가transferModal.tsx의getLineBadgeStyle과 거의 동일합니다 — 공통 유틸로 추출을 권장합니다.이 함수(~60줄)는
components/modal/transferModal.tsx의getLineBadgeStyle과 동일한 호선→색상 매핑 로직을 포함하고 있습니다. 새로운 노선이 추가되거나 색상이 변경될 때 두 곳을 모두 수정해야 하므로 유지보수 부담이 됩니다.
lib/또는utils/디렉토리에 공통 함수로 추출하여 두 파일에서 import하는 것이 좋습니다.#!/bin/bash # 코드베이스 내 동일한 호선 색상 매핑 로직이 또 있는지 확인 rg -n "getLineColor\|getLineBadgeStyle\|bg-\[`#004A85`\]" --type=ts --type=tsx -g '!node_modules/**' | head -40🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/result/`[id]/page.tsx around lines 147 - 206, Extract the duplicate subway line→color mapping into a shared utility (e.g., lib/lineColors.ts or utils/lineColors.ts) and replace the local implementations: move the logic currently in getLineColor (in page.tsx) and getLineBadgeStyle (in components/modal/transferModal.tsx) into a single exported function (e.g., getLineColor or getLineBadgeStyle) and import it in both files; ensure the function signature matches existing callers (accepting fullLineName string) and keep the same return values (Tailwind bg- classes) so callers need only the import change.
126-145:removeQueries직후 같은 키에invalidateQueries를 호출하는 것은 불필요합니다.Line 128에서
removeQueries({ queryKey: ['midpoint', id] })로 쿼리를 캐시에서 완전히 제거한 후, Line 131에서 동일한 키로invalidateQueries를 호출합니다.removeQueries는 쿼리 엔트리 자체를 삭제하므로 이후invalidateQueries는 무효화할 대상이 없어 no-op이 됩니다.의도에 따라 둘 중 하나를 선택하세요:
- 캐시를 완전히 제거하고 재접근 시 fresh fetch를 유도하려면
removeQueries만 사용- 기존 데이터를 유지하면서 백그라운드 refetch를 트리거하려면
invalidateQueries만 사용♻️ removeQueries만 사용하는 경우
const clearRelatedCache = useCallback(() => { queryClient.removeQueries({ queryKey: ['midpoint', id] }); queryClient.removeQueries({ queryKey: ['recommend', id] }); - - queryClient.invalidateQueries({ queryKey: ['midpoint', id] }); }, [id, queryClient]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/result/`[id]/page.tsx around lines 126 - 145, The clearRelatedCache function calls queryClient.removeQueries(['midpoint', id]) and then queryClient.invalidateQueries(['midpoint', id']) which is redundant because removeQueries deletes the entry; update clearRelatedCache (and any callers like handleModifyStart and the useEffect cleanup) to use either removeQueries only to fully drop the cache or replace removeQueries with invalidateQueries only to keep data and trigger a background refetch—pick the intended behavior and remove the other call (references: clearRelatedCache, queryClient.removeQueries, queryClient.invalidateQueries, handleModifyStart, useEffect, id).
114-122: 한글 종성 판별 로직은 정확하지만, 비한글 문자에 대한 방어 코드가 없습니다.
(lastChar - 0xAC00) % 28연산은lastChar가 한글 완성형 음절(U+AC00~U+D7A3) 범위에 있을 때만 유효합니다. 카테고리가 숫자나 영문으로 끝나는 경우 잘못된 결과를 반환할 수 있습니다. 현재 카테고리가 항상 한글이라면 큰 문제는 아니지만, 방어적으로 범위 체크를 추가하면 안전합니다.🛡️ 방어 코드 제안
const getCategoryText = (category: string | undefined): string => { if (!category) return '밍글링 추천 1위'; const lastChar = category.charCodeAt(category.length - 1); + const isKoreanSyllable = lastChar >= 0xAC00 && lastChar <= 0xD7A3; - const hasJongseong = (lastChar - 0xac00) % 28 !== 0; + const hasJongseong = isKoreanSyllable && (lastChar - 0xAC00) % 28 !== 0; return `${category}${hasJongseong ? '이' : '가'} 많은 장소`; };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/result/`[id]/page.tsx around lines 114 - 122, The getCategoryText function uses (lastChar - 0xAC00) % 28 which only makes sense for Hangul syllables; add a defensive Unicode range check in getCategoryText: compute lastCharCode from category.charCodeAt(...), verify it is within 0xAC00..0xD7A3 before computing hasJongseong, and if it's outside that range fall back to a sensible default (e.g., treat as no jongseong so use '가'); update the existing lastChar/hasJongseong logic inside getCategoryText accordingly to avoid incorrect results for non-Korean endings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@app/result/`[id]/page.tsx:
- Line 227: Replace the invalid percentage-based letter-spacing class
tracking-[-1.94%] in the div with a valid unit-based tracking value (e.g.,
tracking-[-1.94px] or tracking-[-0.02em]) so browsers won't ignore it; update
the className on the div in page.tsx (and mirror the same change in
transferModal.tsx where the same tracking-[-1.94%] is used) to use Tailwind
arbitrary unit syntax for letter-spacing with px or em units.
---
Nitpick comments:
In `@app/result/`[id]/page.tsx:
- Around line 147-206: Extract the duplicate subway line→color mapping into a
shared utility (e.g., lib/lineColors.ts or utils/lineColors.ts) and replace the
local implementations: move the logic currently in getLineColor (in page.tsx)
and getLineBadgeStyle (in components/modal/transferModal.tsx) into a single
exported function (e.g., getLineColor or getLineBadgeStyle) and import it in
both files; ensure the function signature matches existing callers (accepting
fullLineName string) and keep the same return values (Tailwind bg- classes) so
callers need only the import change.
- Around line 126-145: The clearRelatedCache function calls
queryClient.removeQueries(['midpoint', id]) and then
queryClient.invalidateQueries(['midpoint', id']) which is redundant because
removeQueries deletes the entry; update clearRelatedCache (and any callers like
handleModifyStart and the useEffect cleanup) to use either removeQueries only to
fully drop the cache or replace removeQueries with invalidateQueries only to
keep data and trigger a background refetch—pick the intended behavior and remove
the other call (references: clearRelatedCache, queryClient.removeQueries,
queryClient.invalidateQueries, handleModifyStart, useEffect, id).
- Around line 114-122: The getCategoryText function uses (lastChar - 0xAC00) %
28 which only makes sense for Hangul syllables; add a defensive Unicode range
check in getCategoryText: compute lastCharCode from category.charCodeAt(...),
verify it is within 0xAC00..0xD7A3 before computing hasJongseong, and if it's
outside that range fall back to a sensible default (e.g., treat as no jongseong
so use '가'); update the existing lastChar/hasJongseong logic inside
getCategoryText accordingly to avoid incorrect results for non-Korean endings.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
app/result/[id]/page.tsx (1)
132-135:handleModifyStart에서 캐시 중복 제거 발생
handleModifyStart에서clearRelatedCache()를 명시적으로 호출한 뒤,router.replace로 네비게이션하면 컴포넌트가 언마운트되면서useEffectcleanup의clearRelatedCache()가 한 번 더 호출됩니다.removeQueries가 멱등(idempotent)이라 에러는 아니지만, 불필요한 중복입니다. useEffect cleanup에 의존하여 여기서는 명시 호출을 제거해도 됩니다.♻️ 중복 제거 제안
const handleModifyStart = () => { - clearRelatedCache(); router.replace(`/meeting/${id}`); };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/result/`[id]/page.tsx around lines 132 - 135, handleModifyStart currently calls clearRelatedCache() and then router.replace(`/meeting/${id}`), but because the component unmount triggered by router.replace will run the useEffect cleanup that already calls clearRelatedCache(), this causes a redundant duplicate call; remove the explicit clearRelatedCache() invocation from handleModifyStart so it only calls router.replace(`/meeting/${id}`) and let the existing useEffect cleanup handle cache clearing (references: handleModifyStart, clearRelatedCache, router.replace, the useEffect cleanup that calls clearRelatedCache).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/result/`[id]/page.tsx:
- Around line 137-141: The effect currently calls clearRelatedCache() on mount
and unmount which removes the ['midpoint', id] query and causes an immediate
data drop and refetch; change the useEffect so that on mount it calls
queryClient.invalidateQueries(['midpoint', id]) (or a new helper that calls
invalidateQueries) to trigger a background refetch without clearing existing
data, and keep clearRelatedCache() (which performs removeQueries) only in the
cleanup function so removal happens only on unmount; update the useEffect
surrounding clearRelatedCache, and ensure this aligns with the useMidpoint(id)
subscription.
- Around line 117-121: The current jongseong check using lastChar/hasJongseong
can produce wrong results for non-Hangul characters; update the logic around
category, lastChar and hasJongseong to: obtain the final code point with
category.codePointAt(category.length - 1), check it falls in the Hangul
Syllables range (0xAC00..0xD7AF) before performing (codePoint - 0xAC00) % 28,
and default hasJongseong to false for non-Hangul so the fallback renders '가'
correctly; update the variables lastChar and hasJongseong in this block
accordingly (use codePointAt and an explicit range check).
---
Nitpick comments:
In `@app/result/`[id]/page.tsx:
- Around line 132-135: handleModifyStart currently calls clearRelatedCache() and
then router.replace(`/meeting/${id}`), but because the component unmount
triggered by router.replace will run the useEffect cleanup that already calls
clearRelatedCache(), this causes a redundant duplicate call; remove the explicit
clearRelatedCache() invocation from handleModifyStart so it only calls
router.replace(`/meeting/${id}`) and let the existing useEffect cleanup handle
cache clearing (references: handleModifyStart, clearRelatedCache,
router.replace, the useEffect cleanup that calls clearRelatedCache).
|
|
||
| // 카테고리 종성에 따라 "이/가"를 다르게 렌더링 | ||
| const lastChar = category.charCodeAt(category.length - 1); | ||
| const hasJongseong = (lastChar - 0xac00) % 28 !== 0; | ||
| return `${category}${hasJongseong ? '이' : '가'} 많은 장소`; |
There was a problem hiding this comment.
한글 종성 판별 시 비한글 문자에 대한 가드 누락
category의 마지막 글자가 한글 음절(U+AC00~U+D7AF) 범위가 아닌 경우(숫자, 영문, 특수문자 등), (lastChar - 0xAC00) % 28 계산이 잘못된 결과를 반환합니다. 예를 들어 카테고리가 "카페2"일 경우 "이"가 잘못 붙을 수 있습니다.
🛡️ 한글 범위 체크 추가 제안
const lastChar = category.charCodeAt(category.length - 1);
- const hasJongseong = (lastChar - 0xac00) % 28 !== 0;
+ const isKoreanSyllable = lastChar >= 0xac00 && lastChar <= 0xd7af;
+ const hasJongseong = isKoreanSyllable && (lastChar - 0xac00) % 28 !== 0;
return `${category}${hasJongseong ? '이' : '가'} 많은 장소`;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // 카테고리 종성에 따라 "이/가"를 다르게 렌더링 | |
| const lastChar = category.charCodeAt(category.length - 1); | |
| const hasJongseong = (lastChar - 0xac00) % 28 !== 0; | |
| return `${category}${hasJongseong ? '이' : '가'} 많은 장소`; | |
| // 카테고리 종성에 따라 "이/가"를 다르게 렌더링 | |
| const lastChar = category.charCodeAt(category.length - 1); | |
| const isKoreanSyllable = lastChar >= 0xac00 && lastChar <= 0xd7af; | |
| const hasJongseong = isKoreanSyllable && (lastChar - 0xac00) % 28 !== 0; | |
| return `${category}${hasJongseong ? '이' : '가'} 많은 장소`; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/result/`[id]/page.tsx around lines 117 - 121, The current jongseong check
using lastChar/hasJongseong can produce wrong results for non-Hangul characters;
update the logic around category, lastChar and hasJongseong to: obtain the final
code point with category.codePointAt(category.length - 1), check it falls in the
Hangul Syllables range (0xAC00..0xD7AF) before performing (codePoint - 0xAC00) %
28, and default hasJongseong to false for non-Hangul so the fallback renders '가'
correctly; update the variables lastChar and hasJongseong in this block
accordingly (use codePointAt and an explicit range check).
| useEffect(() => { | ||
| clearRelatedCache(); | ||
|
|
||
| return () => clearRelatedCache(); | ||
| }, [clearRelatedCache]); |
There was a problem hiding this comment.
마운트 시 removeQueries가 현재 컴포넌트의 데이터를 제거하여 불필요한 리패치 및 로딩 깜빡임 발생
clearRelatedCache가 마운트 시점에도 호출되면서 ['midpoint', id] 쿼리 데이터를 제거합니다. 이 컴포넌트가 useMidpoint(id)로 같은 쿼리를 구독 중이므로, 마운트 직후 데이터가 사라지고 → 로딩 상태 전환 → 리패치가 발생합니다. 정상적인 네비게이션(최초 진입)에서도 불필요한 리패치와 로딩 UI 깜빡임이 생깁니다.
뒤로가기 시 캐시 무효화가 목적이라면, 언마운트 시에만 캐시를 제거하면 충분합니다. 마운트 시에는 invalidateQueries를 사용하면 기존 데이터를 보여주면서 백그라운드 리패치가 가능합니다.
🔧 수정 제안: 마운트 시 invalidate, 언마운트 시 remove
useEffect(() => {
- clearRelatedCache();
-
- return () => clearRelatedCache();
- }, [clearRelatedCache]);
+ // 마운트 시에는 백그라운드 리패치 (기존 데이터 유지)
+ queryClient.invalidateQueries({ queryKey: ['midpoint', id] });
+ queryClient.invalidateQueries({ queryKey: ['recommend', id] });
+
+ // 언마운트 시에는 캐시 완전 제거 (뒤로가기 캐시 무효화)
+ return () => {
+ queryClient.removeQueries({ queryKey: ['midpoint', id] });
+ queryClient.removeQueries({ queryKey: ['recommend', id] });
+ };
+ }, [id, queryClient]);또는 마운트 시 캐시 무효화가 아예 필요 없다면 언마운트 cleanup만 남기세요:
useEffect(() => {
return () => clearRelatedCache();
}, [clearRelatedCache]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/result/`[id]/page.tsx around lines 137 - 141, The effect currently calls
clearRelatedCache() on mount and unmount which removes the ['midpoint', id]
query and causes an immediate data drop and refetch; change the useEffect so
that on mount it calls queryClient.invalidateQueries(['midpoint', id]) (or a new
helper that calls invalidateQueries) to trigger a background refetch without
clearing existing data, and keep clearRelatedCache() (which performs
removeQueries) only in the cleanup function so removal happens only on unmount;
update the useEffect surrounding clearRelatedCache, and ensure this aligns with
the useMidpoint(id) subscription.
🚀 refactor: 뒤로가기 캐시 무효화 로직 작성
📝 변경사항
✅ 체크리스트
📸 스크린샷
💬 리뷰어 전달사항
Summary by CodeRabbit
릴리스 노트
버그 수정
개선 사항
스타일